home *** CD-ROM | disk | FTP | other *** search
/ EuroCD 3 / EuroCD 3.iso / Games / Doom / ADoom-0.8 / ADoom_src / r_data.c < prev    next >
C/C++ Source or Header  |  1998-06-24  |  19KB  |  869 lines

  1. // Emacs style mode select   -*- C++ -*- 
  2. //-----------------------------------------------------------------------------
  3. //
  4. // $Id:$
  5. //
  6. // Copyright (C) 1993-1996 by id Software, Inc.
  7. //
  8. // This source is available for distribution and/or modification
  9. // only under the terms of the DOOM Source Code License as
  10. // published by id Software. All rights reserved.
  11. //
  12. // The source is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
  15. // for more details.
  16. //
  17. // $Log:$
  18. //
  19. // Revision 1.3  1997/01/29 20:10
  20. // DESCRIPTION:
  21. //    Preparation of data for rendering,
  22. //    generation of lookups, caching, retrieval by name.
  23. //
  24. //-----------------------------------------------------------------------------
  25.  
  26.  
  27. static const char
  28. rcsid[] = "$Id: r_data.c,v 1.4 1997/02/03 16:47:55 b1 Exp $";
  29.  
  30. #include "i_system.h"
  31. #include "z_zone.h"
  32.  
  33. #include "m_swap.h"
  34.  
  35. #include "w_wad.h"
  36.  
  37. #include "doomdef.h"
  38. #include "r_local.h"
  39. #include "p_local.h"
  40.  
  41. #include "doomstat.h"
  42. #include "r_sky.h"
  43.  
  44. #ifdef LINUX
  45. #include  <alloca.h>
  46. #endif
  47.  
  48. #ifdef __SASC
  49. #include <stdlib.h>
  50. #endif
  51.  
  52. #include "r_data.h"
  53.  
  54. //
  55. // Graphics.
  56. // DOOM graphics for walls and sprites
  57. // is stored in vertical runs of opaque pixels (posts).
  58. // A column is composed of zero or more posts,
  59. // a patch or sprite is composed of zero or more columns.
  60. // 
  61.  
  62.  
  63.  
  64. //
  65. // Texture definition.
  66. // Each texture is composed of one or more patches,
  67. // with patches being lumps stored in the WAD.
  68. // The lumps are referenced by number, and patched
  69. // into the rectangular texture space using origin
  70. // and possibly other attributes.
  71. //
  72. typedef struct
  73. {
  74.     short    originx;
  75.     short    originy;
  76.     short    patch;
  77.     short    stepdir;
  78.     short    colormap;
  79. } mappatch_t;
  80.  
  81.  
  82. //
  83. // Texture definition.
  84. // A DOOM wall texture is a list of patches
  85. // which are to be combined in a predefined order.
  86. //
  87. typedef struct
  88. {
  89.     char        name[8];
  90.     boolean        masked;    
  91.     short        width;
  92.     short        height;
  93.     void        **columndirectory;    // OBSOLETE
  94.     short        patchcount;
  95.     mappatch_t    patches[1];
  96. } maptexture_t;
  97.  
  98.  
  99. // A single patch from a texture definition,
  100. //  basically a rectangular area within
  101. //  the texture rectangle.
  102. typedef struct
  103. {
  104.     // Block origin (allways UL),
  105.     // which has allready accounted
  106.     // for the internal origin of the patch.
  107.     int        originx;    
  108.     int        originy;
  109.     int        patch;
  110. } texpatch_t;
  111.  
  112.  
  113. // A maptexturedef_t describes a rectangular texture,
  114. //  which is composed of one or more mappatch_t structures
  115. //  that arrange graphic patches.
  116. typedef struct
  117. {
  118.     // Keep name for switch changing, etc.
  119.     char    name[8];        
  120.     short    width;
  121.     short    height;
  122.     
  123.     // All the patches[patchcount]
  124.     //  are drawn back to front into the cached texture.
  125.     short    patchcount;
  126.     texpatch_t    patches[1];        
  127.     
  128. } texture_t;
  129.  
  130.  
  131.  
  132. int        firstflat;
  133. int        lastflat;
  134. int        numflats;
  135.  
  136. int        firstpatch;
  137. int        lastpatch;
  138. int        numpatches;
  139.  
  140. int        firstspritelump;
  141. int        lastspritelump;
  142. int        numspritelumps;
  143.  
  144. int        numtextures;
  145. texture_t**    textures;
  146.  
  147.  
  148. int*            texturewidthmask;
  149. // needed for texture pegging
  150. fixed_t*        textureheight;        
  151. int*            texturecompositesize;
  152. short**            texturecolumnlump;
  153. unsigned short**    texturecolumnofs;
  154. byte**            texturecomposite;
  155.  
  156. // for global animation
  157. int*        flattranslation;
  158. int*        texturetranslation;
  159.  
  160. // needed for pre rendering
  161. fixed_t*    spritewidth;    
  162. fixed_t*    spriteoffset;
  163. fixed_t*    spritetopoffset;
  164.  
  165. lighttable_t    *colormaps;
  166.  
  167.  
  168. //
  169. // MAPTEXTURE_T CACHING
  170. // When a texture is first needed,
  171. //  it counts the number of composite columns
  172. //  required in the texture and allocates space
  173. //  for a column directory and any new columns.
  174. // The directory will simply point inside other patches
  175. //  if there is only one patch in a given column,
  176. //  but any columns with multiple patches
  177. //  will have new column_ts generated.
  178. //
  179.  
  180.  
  181.  
  182. //
  183. // R_DrawColumnInCache
  184. // Clip and draw a column
  185. //  from a patch into a cached post.
  186. //
  187. void
  188. R_DrawColumnInCache
  189. ( column_t*    patch,
  190.   byte*        cache,
  191.   int        originy,
  192.   int        cacheheight )
  193. {
  194.     int        count;
  195.     int        position;
  196.     byte*    source;
  197.     byte*    dest;
  198.     
  199.     dest = (byte *)cache + 3;
  200.     
  201.     while (patch->topdelta != 0xff)
  202.     {
  203.     source = (byte *)patch + 3;
  204.     count = patch->length;
  205.     position = originy + patch->topdelta;
  206.  
  207.     if (position < 0)
  208.     {
  209.         count += position;
  210.         position = 0;
  211.     }
  212.  
  213.     if (position + count > cacheheight)
  214.         count = cacheheight - position;
  215.  
  216.     if (count > 0)
  217.         memcpy (cache + position, source, count);
  218.         
  219.     patch = (column_t *)(  (byte *)patch + patch->length + 4); 
  220.     }
  221. }
  222.  
  223.  
  224.  
  225. //
  226. // R_GenerateComposite
  227. // Using the texture definition,
  228. //  the composite texture is created from the patches,
  229. //  and each column is cached.
  230. //
  231. void R_GenerateComposite (int texnum)
  232. {
  233.     byte*        block;
  234.     texture_t*        texture;
  235.     texpatch_t*        patch;    
  236.     patch_t*        realpatch;
  237.     int            x;
  238.     int            x1;
  239.     int            x2;
  240.     int            i;
  241.     column_t*        patchcol;
  242.     short*        collump;
  243.     unsigned short*    colofs;
  244.     
  245.     texture = textures[texnum];
  246.  
  247.     block = Z_Malloc (texturecompositesize[texnum],
  248.               PU_STATIC, 
  249.               &texturecomposite[texnum]);    
  250.  
  251.     collump = texturecolumnlump[texnum];
  252.     colofs = texturecolumnofs[texnum];
  253.     
  254.     // Composite the columns together.
  255.     patch = texture->patches;
  256.         
  257.     for (i=0 , patch = texture->patches;
  258.      i<texture->patchcount;
  259.      i++, patch++)
  260.     {
  261.     realpatch = W_CacheLumpNum (patch->patch, PU_CACHE);
  262.     x1 = patch->originx;
  263.     x2 = x1 + SHORT(realpatch->width);
  264.  
  265.     if (x1<0)
  266.         x = 0;
  267.     else
  268.         x = x1;
  269.     
  270.     if (x2 > texture->width)
  271.         x2 = texture->width;
  272.  
  273.     for ( ; x<x2 ; x++)
  274.     {
  275.         // Column does not have multiple patches?
  276.         if (collump[x] >= 0)
  277.         continue;
  278.         
  279.         patchcol = (column_t *)((byte *)realpatch
  280.                     + LONG(realpatch->columnofs[x-x1]));
  281.         R_DrawColumnInCache (patchcol,
  282.                  block + colofs[x],
  283.                  patch->originy,
  284.                  texture->height);
  285.     }
  286.                         
  287.     }
  288.  
  289.     // Now that the texture has been built in column cache,
  290.     //  it is purgable from zone memory.
  291.     Z_ChangeTag (block, PU_CACHE);
  292. }
  293.  
  294.  
  295.  
  296. //
  297. // R_GenerateLookup
  298. //
  299. void R_GenerateLookup (int texnum)
  300. {
  301.     texture_t*        texture;
  302.     byte*        patchcount = NULL; // patchcount[texture->width]
  303.     texpatch_t*        patch;    
  304.     patch_t*        realpatch;
  305.     int            x;
  306.     int            x1;
  307.     int            x2;
  308.     int            i;
  309.     short*        collump;
  310.     unsigned short*    colofs;
  311.     
  312.     texture = textures[texnum];
  313.  
  314.     // Composited texture not created yet.
  315.     texturecomposite[texnum] = 0;
  316.     
  317.     texturecompositesize[texnum] = 0;
  318.     collump = texturecolumnlump[texnum];
  319.     colofs = texturecolumnofs[texnum];
  320.     
  321.     // Now count the number of columns
  322.     //  that are covered by more than one patch.
  323.     // Fill in the lump / offset, so columns
  324.     //  with only a single patch are all done.
  325.     if ((patchcount = (byte *)malloc (texture->width)) == NULL)
  326.       I_Error ("malloc(%d) failed", texture->width);
  327.     memset (patchcount, 0, texture->width);
  328.     patch = texture->patches;
  329.         
  330.     for (i=0 , patch = texture->patches;
  331.      i<texture->patchcount;
  332.      i++, patch++)
  333.     {
  334.     realpatch = W_CacheLumpNum (patch->patch, PU_CACHE);
  335.     x1 = patch->originx;
  336.     x2 = x1 + SHORT(realpatch->width);
  337.     
  338.     if (x1 < 0)
  339.         x = 0;
  340.     else
  341.         x = x1;
  342.  
  343.     if (x2 > texture->width)
  344.         x2 = texture->width;
  345.     for ( ; x<x2 ; x++)
  346.     {
  347.         patchcount[x]++;
  348.         collump[x] = patch->patch;
  349.         colofs[x] = LONG(realpatch->columnofs[x-x1])+3;
  350.     }
  351.     }
  352.     
  353.     for (x=0 ; x<texture->width ; x++)
  354.     {
  355.     if (!patchcount[x])
  356.     {
  357.         printf ("R_GenerateLookup: column without a patch (%s)\n",
  358.             texture->name);
  359.         return;
  360.     }
  361.     // I_Error ("R_GenerateLookup: column without a patch");
  362.     
  363.     if (patchcount[x] > 1)
  364.     {
  365.         // Use the cached block.
  366.         collump[x] = -1;    
  367.         colofs[x] = texturecompositesize[texnum];
  368.         
  369.         if (texturecompositesize[texnum] > 0x10000-texture->height)
  370.         {
  371.         I_Error ("R_GenerateLookup: texture %i is >64k",
  372.              texnum);
  373.         }
  374.         
  375.         texturecompositesize[texnum] += texture->height;
  376.     }
  377.     }    
  378.     if (patchcount != NULL)
  379.       free (patchcount);
  380. }
  381.  
  382.  
  383.  
  384.  
  385. //
  386. // R_GetColumn
  387. //
  388. byte*
  389. R_GetColumn
  390. ( int        tex,
  391.   int        col )
  392. {
  393.     int        lump;
  394.     int        ofs;
  395.     
  396.     col &= texturewidthmask[tex];
  397.     lump = texturecolumnlump[tex][col];
  398.     ofs = texturecolumnofs[tex][col];
  399.     
  400.     if (lump > 0)
  401.     return (byte *)W_CacheLumpNum(lump,PU_CACHE)+ofs;
  402.  
  403.     if (!texturecomposite[tex])
  404.     R_GenerateComposite (tex);
  405.  
  406.     return texturecomposite[tex] + ofs;
  407. }
  408.  
  409.  
  410.  
  411.  
  412. //
  413. // R_InitTextures
  414. // Initializes the texture list
  415. //  with the textures from the world map.
  416. //
  417. void R_InitTextures (void)
  418. {
  419.     maptexture_t*    mtexture;
  420.     texture_t*        texture;
  421.     mappatch_t*        mpatch;
  422.     texpatch_t*        patch;
  423.  
  424.     int            i;
  425.     int            j;
  426.  
  427.     int*        maptex;
  428.     int*        maptex2;
  429.     int*        maptex1;
  430.     
  431.     char        name[9];
  432.     char*        names;
  433.     char*        name_p;
  434.     
  435.     int*        patchlookup = NULL;
  436.     
  437.     int            totalwidth;
  438.     int            nummappatches;
  439.     int            offset;
  440.     int            maxoff;
  441.     int            maxoff2;
  442.     int            numtextures1;
  443.     int            numtextures2;
  444.  
  445.     int*        directory;
  446.     
  447.     int            temp1;
  448.     int            temp2;
  449.     int            temp3;
  450.  
  451.     
  452.     // Load the patch names from pnames.lmp.
  453.     name[8] = 0;    
  454.     names = W_CacheLumpName ("PNAMES", PU_STATIC);
  455.     nummappatches = LONG ( *((int *)names) );
  456.     name_p = names+4;
  457.     if ((patchlookup = malloc (nummappatches*sizeof(*patchlookup))) == NULL)
  458.       I_Error ("malloc(%d) failed", nummappatches*sizeof(*patchlookup));
  459.     
  460.     for (i=0 ; i<nummappatches ; i++)
  461.     {
  462.     strncpy (name,name_p+i*8, 8);
  463.     patchlookup[i] = W_CheckNumForName (name);
  464.     }
  465.     Z_Free (names);
  466.     
  467.     // Load the map texture definitions from textures.lmp.
  468.     // The data is contained in one or two lumps,
  469.     //  TEXTURE1 for shareware, plus TEXTURE2 for commercial.
  470.     maptex = maptex1 = W_CacheLumpName ("TEXTURE1", PU_STATIC);
  471.     numtextures1 = LONG(*maptex);
  472.     maxoff = W_LumpLength (W_GetNumForName ("TEXTURE1"));
  473.     directory = maptex+1;
  474.     
  475.     if (W_CheckNumForName ("TEXTURE2") != -1)
  476.     {
  477.     maptex2 = W_CacheLumpName ("TEXTURE2", PU_STATIC);
  478.     numtextures2 = LONG(*maptex2);
  479.     maxoff2 = W_LumpLength (W_GetNumForName ("TEXTURE2"));
  480.     }
  481.     else
  482.     {
  483.     maptex2 = NULL;
  484.     numtextures2 = 0;
  485.     maxoff2 = 0;
  486.     }
  487.     numtextures = numtextures1 + numtextures2;
  488.     
  489.     textures = Z_Malloc (numtextures*4, PU_STATIC, 0);
  490.     texturecolumnlump = Z_Malloc (numtextures*4, PU_STATIC, 0);
  491.     texturecolumnofs = Z_Malloc (numtextures*4, PU_STATIC, 0);
  492.     texturecomposite = Z_Malloc (numtextures*4, PU_STATIC, 0);
  493.     texturecompositesize = Z_Malloc (numtextures*4, PU_STATIC, 0);
  494.     texturewidthmask = Z_Malloc (numtextures*4, PU_STATIC, 0);
  495.     textureheight = Z_Malloc (numtextures*4, PU_STATIC, 0);
  496.  
  497.     totalwidth = 0;
  498.     
  499.     //    Really complex printing shit...
  500.     temp1 = W_GetNumForName ("S_START");  // P_???????
  501.     temp2 = W_GetNumForName ("S_END") - 1;
  502.     temp3 = ((temp2-temp1+63)/64) + ((numtextures+63)/64);
  503.     printf("[");
  504.     for (i = 0; i < temp3; i++)
  505.     printf(" ");
  506.     printf("         ]");
  507.     for (i = 0; i < temp3; i++)
  508.     printf("\x8");
  509.     printf("\x8\x8\x8\x8\x8\x8\x8\x8\x8\x8");    
  510.     
  511.     for (i=0 ; i<numtextures ; i++, directory++)
  512.     {
  513.     if (!(i&63))
  514.         printf (".");
  515.  
  516.     if (i == numtextures1)
  517.     {
  518.         // Start looking in second texture file.
  519.         maptex = maptex2;
  520.         maxoff = maxoff2;
  521.         directory = maptex+1;
  522.     }
  523.         
  524.     offset = LONG(*directory);
  525.  
  526.     if (offset > maxoff)
  527.         I_Error ("R_InitTextures: bad texture directory");
  528.     
  529.     mtexture = (maptexture_t *) ( (byte *)maptex + offset);
  530.  
  531.     texture = textures[i] =
  532.         Z_Malloc (sizeof(texture_t)
  533.               + sizeof(texpatch_t)*(SHORT(mtexture->patchcount)-1),
  534.               PU_STATIC, 0);
  535.     
  536.     texture->width = SHORT(mtexture->width);
  537.     texture->height = SHORT(mtexture->height);
  538.     texture->patchcount = SHORT(mtexture->patchcount);
  539.  
  540.     memcpy (texture->name, mtexture->name, sizeof(texture->name));
  541.     mpatch = &mtexture->patches[0];
  542.     patch = &texture->patches[0];
  543.  
  544.     for (j=0 ; j<texture->patchcount ; j++, mpatch++, patch++)
  545.     {
  546.         patch->originx = SHORT(mpatch->originx);
  547.         patch->originy = SHORT(mpatch->originy);
  548.         patch->patch = patchlookup[SHORT(mpatch->patch)];
  549.         if (patch->patch == -1)
  550.         {
  551.         I_Error ("R_InitTextures: Missing patch in texture %s",
  552.              texture->name);
  553.         }
  554.     }        
  555.     texturecolumnlump[i] = Z_Malloc (texture->width*2, PU_STATIC,0);
  556.     texturecolumnofs[i] = Z_Malloc (texture->width*2, PU_STATIC,0);
  557.  
  558.     j = 1;
  559.     while (j*2 <= texture->width)
  560.         j<<=1;
  561.  
  562.     texturewidthmask[i] = j-1;
  563.     textureheight[i] = texture->height<<FRACBITS;
  564.         
  565.     totalwidth += texture->width;
  566.     }
  567.  
  568.     Z_Free (maptex1);
  569.     if (maptex2)
  570.     Z_Free (maptex2);
  571.     
  572.     // Precalculate whatever possible.    
  573.     for (i=0 ; i<numtextures ; i++)
  574.     R_GenerateLookup (i);
  575.     
  576.     // Create translation table for global animation.
  577.     texturetranslation = Z_Malloc ((numtextures+1)*4, PU_STATIC, 0);
  578.     
  579.     for (i=0 ; i<numtextures ; i++)
  580.     texturetranslation[i] = i;
  581.  
  582.     if (patchlookup != NULL)
  583.       free (patchlookup);
  584. }
  585.  
  586.  
  587.  
  588. //
  589. // R_InitFlats
  590. //
  591. void R_InitFlats (void)
  592. {
  593.     int        i;
  594.     
  595.     firstflat = W_GetNumForName ("F_START") + 1;
  596.     lastflat = W_GetNumForName ("F_END") - 1;
  597.     numflats = lastflat - firstflat + 1;
  598.     
  599.     // Create translation table for global animation.
  600.     flattranslation = Z_Malloc ((numflats+1)*4, PU_STATIC, 0);
  601.     
  602.     for (i=0 ; i<numflats ; i++)
  603.     flattranslation[i] = i;
  604. }
  605.  
  606.  
  607. //
  608. // R_InitSpriteLumps
  609. // Finds the width and hoffset of all sprites in the wad,
  610. //  so the sprite does not need to be cached completely
  611. //  just for having the header info ready during rendering.
  612. //
  613. void R_InitSpriteLumps (void)
  614. {
  615.     int        i;
  616.     patch_t    *patch;
  617.     
  618.     firstspritelump = W_GetNumForName ("S_START") + 1;
  619.     lastspritelump = W_GetNumForName ("S_END") - 1;
  620.     
  621.     numspritelumps = lastspritelump - firstspritelump + 1;
  622.     spritewidth = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
  623.     spriteoffset = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
  624.     spritetopoffset = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
  625.     
  626.     for (i=0 ; i< numspritelumps ; i++)
  627.     {
  628.     if (!(i&63))
  629.         printf (".");
  630.  
  631.     patch = W_CacheLumpNum (firstspritelump+i, PU_CACHE);
  632.     spritewidth[i] = SHORT(patch->width)<<FRACBITS;
  633.     spriteoffset[i] = SHORT(patch->leftoffset)<<FRACBITS;
  634.     spritetopoffset[i] = SHORT(patch->topoffset)<<FRACBITS;
  635.     }
  636. }
  637.  
  638.  
  639.  
  640. //
  641. // R_InitColormaps
  642. //
  643. void R_InitColormaps (void)
  644. {
  645.     int    lump, length;
  646.     
  647.     // Load in the light tables, 
  648.     //  256 byte align tables.
  649.     lump = W_GetNumForName("COLORMAP"); 
  650.     length = W_LumpLength (lump) + 255; 
  651.     colormaps = Z_Malloc (length, PU_STATIC, 0); 
  652.     colormaps = (byte *)( ((int)colormaps + 255)&~0xff); 
  653.     W_ReadLump (lump,colormaps); 
  654. }
  655.  
  656.  
  657.  
  658. //
  659. // R_InitData
  660. // Locates all the lumps
  661. //  that will be used by all views
  662. // Must be called after W_Init.
  663. //
  664. void R_InitData (void)
  665. {
  666.     R_InitTextures ();
  667.     printf ("\nInitTextures");
  668.     R_InitFlats ();
  669.     printf ("\nInitFlats");
  670.     R_InitSpriteLumps ();
  671.     printf ("\nInitSprites");
  672.     R_InitColormaps ();
  673.     printf ("\nInitColormaps");
  674. }
  675.  
  676.  
  677.  
  678. //
  679. // R_FlatNumForName
  680. // Retrieval, get a flat number for a flat name.
  681. //
  682. int R_FlatNumForName (char* name)
  683. {
  684.     int        i;
  685.     char    namet[9];
  686.  
  687.     i = W_CheckNumForName (name);
  688.  
  689.     if (i == -1)
  690.     {
  691.     namet[8] = 0;
  692.     memcpy (namet, name,8);
  693.     I_Error ("R_FlatNumForName: %s not found",namet);
  694.     }
  695.     return i - firstflat;
  696. }
  697.  
  698.  
  699.  
  700.  
  701. //
  702. // R_CheckTextureNumForName
  703. // Check whether texture is available.
  704. // Filter out NoTexture indicator.
  705. //
  706. int    R_CheckTextureNumForName (char *name)
  707. {
  708.     int        i;
  709.  
  710.     // "NoTexture" marker.
  711.     if (name[0] == '-')        
  712.     return 0;
  713.         
  714.     for (i=0 ; i<numtextures ; i++)
  715.     if (!strncasecmp (textures[i]->name, name, 8) )
  716.         return i;
  717.         
  718.     return -1;
  719. }
  720.  
  721.  
  722.  
  723. //
  724. // R_TextureNumForName
  725. // Calls R_CheckTextureNumForName,
  726. //  aborts with error message.
  727. //
  728. int    R_TextureNumForName (char* name)
  729. {
  730.     int        i;
  731.     
  732.     i = R_CheckTextureNumForName (name);
  733.  
  734.     if (i==-1)
  735.     {
  736.     I_Error ("R_TextureNumForName: %s not found",
  737.          name);
  738.     }
  739.     return i;
  740. }
  741.  
  742.  
  743.  
  744.  
  745. //
  746. // R_PrecacheLevel
  747. // Preloads all relevant graphics for the level.
  748. //
  749. int        flatmemory;
  750. int        texturememory;
  751. int        spritememory;
  752.  
  753. void R_PrecacheLevel (void)
  754. {
  755.     char*        flatpresent = NULL;
  756.     char*        texturepresent = NULL;
  757.     char*        spritepresent = NULL;
  758.  
  759.     int            i;
  760.     int            j;
  761.     int            k;
  762.     int            lump;
  763.     
  764.     texture_t*        texture;
  765.     thinker_t*        th;
  766.     spriteframe_t*    sf;
  767.  
  768.     if (demoplayback)
  769.     return;
  770.     
  771.     // Precache flats.
  772.     if ((flatpresent = malloc(numflats)) == NULL)
  773.       I_Error ("malloc(%d) failed", numflats);
  774.     memset (flatpresent,0,numflats);    
  775.  
  776.     for (i=0 ; i<numsectors ; i++)
  777.     {
  778.     flatpresent[sectors[i].floorpic] = 1;
  779.     flatpresent[sectors[i].ceilingpic] = 1;
  780.     }
  781.     
  782.     flatmemory = 0;
  783.  
  784.     for (i=0 ; i<numflats ; i++)
  785.     {
  786.     if (flatpresent[i])
  787.     {
  788.         lump = firstflat + i;
  789.         flatmemory += lumpinfo[lump].size;
  790.         W_CacheLumpNum(lump, PU_CACHE);
  791.     }
  792.     }
  793.     
  794.     // Precache textures.
  795.     if ((texturepresent = malloc(numtextures)) == NULL)
  796.       I_Error ("malloc(%d) failed", numtextures);
  797.     memset (texturepresent,0, numtextures);
  798.     
  799.     for (i=0 ; i<numsides ; i++)
  800.     {
  801.     texturepresent[sides[i].toptexture] = 1;
  802.     texturepresent[sides[i].midtexture] = 1;
  803.     texturepresent[sides[i].bottomtexture] = 1;
  804.     }
  805.  
  806.     // Sky texture is always present.
  807.     // Note that F_SKY1 is the name used to
  808.     //  indicate a sky floor/ceiling as a flat,
  809.     //  while the sky texture is stored like
  810.     //  a wall texture, with an episode dependend
  811.     //  name.
  812.     texturepresent[skytexture] = 1;
  813.     
  814.     texturememory = 0;
  815.     for (i=0 ; i<numtextures ; i++)
  816.     {
  817.     if (!texturepresent[i])
  818.         continue;
  819.  
  820.     texture = textures[i];
  821.     
  822.     for (j=0 ; j<texture->patchcount ; j++)
  823.     {
  824.         lump = texture->patches[j].patch;
  825.         texturememory += lumpinfo[lump].size;
  826.         W_CacheLumpNum(lump , PU_CACHE);
  827.     }
  828.     }
  829.     
  830.     // Precache sprites.
  831.     if ((spritepresent = malloc(numsprites)) == NULL)
  832.       I_Error ("malloc(%d) failed", numsprites);
  833.     memset (spritepresent,0, numsprites);
  834.     
  835.     for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
  836.     {
  837.     if (th->function.acp1 == (actionf_p1)P_MobjThinker)
  838.         spritepresent[((mobj_t *)th)->sprite] = 1;
  839.     }
  840.     
  841.     spritememory = 0;
  842.     for (i=0 ; i<numsprites ; i++)
  843.     {
  844.     if (!spritepresent[i])
  845.         continue;
  846.  
  847.     for (j=0 ; j<sprites[i].numframes ; j++)
  848.     {
  849.         sf = &sprites[i].spriteframes[j];
  850.         for (k=0 ; k<8 ; k++)
  851.         {
  852.         lump = firstspritelump + sf->lump[k];
  853.         spritememory += lumpinfo[lump].size;
  854.         W_CacheLumpNum(lump , PU_CACHE);
  855.         }
  856.     }
  857.     }
  858.     if (flatpresent != NULL)
  859.       free (flatpresent);
  860.     if (texturepresent != NULL)
  861.       free (texturepresent);
  862.     if (spritepresent != NULL)
  863.       free (spritepresent);
  864. }
  865.  
  866.  
  867.  
  868.  
  869.